home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 7 / BBS in a Box - Macintosh - Volume VII (BBS in a Box) (January 1993).iso / Files / Tele / C / Comet2.1.3.cpt / Comet / 3270token.c < prev    next >
Text File  |  1991-07-26  |  19KB  |  860 lines

  1. /*
  2.     Copyright Cornell University 1986.  All rights are reserved.
  3.  
  4.     3270token.c consists of token processing, keyboard mapping 
  5.     & translation routines for the IBM 3270 emulator
  6. */
  7.  
  8.  
  9. #include <em.h>
  10.  
  11. #include <3270.h>
  12. #include <rcodes.h>
  13.  
  14. #include <macdefs.h>
  15. #include <h19.h>
  16.  
  17. #define IBMPASTEMODE    1        /* paste, abort on protected field entry */
  18. #define IBMPASTETAB        2        /* paste, try skipping protected field on char entry */
  19. #define IBMPASTEABORT    3
  20.  
  21. int pastemode = FALSE;                /* flag for ibmsendchar() to abort on protected */
  22.  
  23. extern unsigned char pfkeymap();    /* forward declaration */
  24.  
  25. ibmproc_token(tkptr)
  26. struct token *tkptr;
  27. {
  28.     unsigned char *ptr;
  29.     extern int icon_up;
  30.     static int nselystart = 0;
  31.     static int nselxstart = 0;
  32.     static int nselyend = 0;
  33.     static int nselxend = 0;
  34.  
  35. #ifdef ICONLOCKS            
  36.     if (icon_up && !hycactive) {
  37.         /* allow no input if the window has been shrunk--unless tndrvr running */
  38.         beep();
  39.         return(0);
  40.     }
  41. #endif
  42.  
  43.     if (emdp->event_reg & KYBD_LOCK) {
  44.         if ((tkptr->class == RSLT_LCAC) && (tkptr->entry == RESET))
  45.             /* fall through to do it */
  46.             flushactions(emdp);            /* kill all actions remaining */
  47.         else {
  48.             beep();
  49.             return(0);
  50.         }
  51.     }
  52.     if (emdp->event_reg & TFTP_ON)
  53.     {
  54.         if ((tkptr->class == RSLT_PFKY) && (tkptr->entry == PA1))
  55.             ft_usr();
  56.         return(-1);
  57.     }
  58.  
  59.     switch(tkptr->class) {
  60.         case RSLT_ASCI: {
  61.             /* ascii character */
  62.             if (emdp->event_reg & SYS_LOCK)
  63.                 return(-1);
  64.  
  65.             ibmsendchar(tkptr->entry);
  66.             break;
  67.         }
  68.         case RSLT_EDIT: {
  69.             if (stdedit(tkptr->entry)) {
  70.                 /* stdedit didn't handle the item */
  71.                 if (emdp->event_reg & SYS_LOCK)
  72.                     return(-1);
  73.     
  74.                 if (tkptr->entry == ED_PASTE) {
  75.                     /* take the current scrap & feed it into proc_token? */
  76.                     long scraplen;
  77.                     unsigned char * thep;
  78.                     unsigned char thechar;
  79.                     
  80.                     scraplen = gettextscrap(&thep);
  81.  
  82.                     /* paste w/ respect for 3270 limitations */
  83.                     pastemode = IBMPASTEMODE;                 /* set flag for sendchar */
  84.                     while (scraplen-- > 0) {
  85.                         if ((thechar = *thep++) == CR) {
  86.                             /* do a Line Feed when we see a CR */
  87.                             ibmmvcurs(NEW_LINE);
  88.                             setibmcursor();
  89.                         }
  90.                         else if (thechar == TAB) {
  91.                             /* make four spaces for a TAB ? */
  92.                             ibmsendchar(' ');
  93.                             ibmsendchar(' ');
  94.                             ibmsendchar(' ');
  95.                             ibmsendchar(' ');
  96.                         }
  97.                         else if (thechar == PT) {
  98.                             /* do a 3270 TAB */
  99.                             ibmmvcurs(TAB_FWD);
  100.                             setibmcursor();
  101.                         }
  102.                         else if (thechar == CTLB) {
  103.                             /* go ahead and TAB to new fields rather than aborting */
  104.                             pastemode = IBMPASTETAB;
  105.                         }
  106.                         else {
  107.                             ibmsendchar(thechar);
  108.                         }
  109.                         if (pastemode == IBMPASTEABORT) {
  110.                             /* abort on error */
  111.                             beep();
  112.                             break;
  113.                         }
  114.                     }
  115.                     releasescrap();
  116.                     pastemode = FALSE;                 /* set flag for sendchar */
  117.                     break;
  118.                 }
  119.                 else
  120.                     entryerr(tkptr);
  121.             }
  122.             break;
  123.         }
  124.         case RSLT_PFKY: {
  125.             /* program function key, enter, clear    */ 
  126.             if (emdp->event_reg & SYS_LOCK)
  127.                 return(-1);
  128.  
  129.             switch (tkptr->entry) {
  130.                 case PFSHIFT: {
  131.                     if (emdp->pfdubshift) 
  132.                         return(0);
  133.                     if (!emdp->pfshift) {
  134.                         emdp->pfshift = TRUE;
  135.                         pfshowshift();
  136.                     }
  137.                     else {
  138.                         emdp->pfshift = FALSE;
  139.                         pfclrshift();
  140.                     }
  141.                     return(0);
  142.                 }
  143.                 case PFDUBSHIFT: {
  144.                     if (emdp->pfshift) 
  145.                         return(0);
  146.                     if (emdp->pfdubshift) {
  147.                         emdp->pfdubshift = TRUE;
  148.                         pfshowdubshift();
  149.                     }
  150.                     else {
  151.                         emdp->pfdubshift = FALSE;
  152.                         pfclrdubshift();
  153.                     }
  154.                     return(0);
  155.                 }
  156.                 case PF1: 
  157.                 case PF2:
  158.                 case PF3: 
  159.                 case PF4:
  160.                 case PF5: 
  161.                 case PF6:
  162.                 case PF7:
  163.                 case PF8:
  164.                 case PF9:
  165.                 case PF10:
  166.                 case PF11:
  167.                 case PF12: {
  168.                     /* a pf key should be sent, check for shift */
  169.                     if (emdp->pfshift) {
  170.                         emdp->pfshift = FALSE;
  171.                         emdp->pfdubshift = FALSE;
  172.                         pfclrshift();
  173.                         pfclrdubshift();
  174.                         tkptr->entry += 12; 
  175.                     }
  176.                     else if (emdp->pfdubshift) {
  177.                         emdp->pfshift = FALSE;
  178.                         emdp->pfdubshift = FALSE;
  179.                         pfclrshift();
  180.                         pfclrdubshift();
  181.                         tkptr->entry += 24;
  182.                     }
  183.                     break;
  184.                 }
  185.                 default: {
  186.                     break;
  187.                     /* fall through to send others-- PA1, Enter, etc. */
  188.                 }
  189.             }
  190.             ibmsendpf(tkptr->entry);
  191.             return(0);
  192.         }
  193.         case RSLT_MVCR: {
  194.              /* cursor movement key */ 
  195.             if (emdp->event_reg & SYS_LOCK)
  196.                 return(-1);
  197.  
  198.             if (ibmmvcurs((short) tkptr->entry))
  199.                 entryerr(tkptr);
  200.             else
  201.                 /* set the ibm cursor to the new position */
  202.                 setibmcursor();
  203.             return(0);
  204.         }
  205.         case RSLT_YCURS:  {
  206.             /* move to beginning of line y */
  207.             if (emdp->event_reg & SYS_LOCK)
  208.                 return(-1);
  209.  
  210.             cursor_ptr = scr_map + ((unsigned int) tkptr->entry * emdp->linelength);
  211.             if (cursor_ptr >= smap_end)
  212.                 cursor_ptr = scr_map;
  213.  
  214.             /* fix current attribute */
  215.             if (*cursor_ptr < ATTR)
  216.                 current_attr = cursor_ptr;
  217.             else {
  218.                 if ((ptr = look_attr(cursor_ptr,BACK)) != NULL)
  219.                     current_attr = ptr;
  220.             }
  221.             newibmcursor();
  222.             return(0);
  223.         }
  224.         case RSLT_XCURS: {
  225.             /* move to x on current line */
  226.             int curxpos;
  227.  
  228.             if (emdp->event_reg & SYS_LOCK)
  229.                 return(-1);
  230.  
  231.             curxpos = tkptr->entry - ((cursor_ptr - scr_map) % emdp->linelength);
  232.             cursor_ptr += curxpos;
  233.                 /* current y offset + x given in entry */
  234.             if (cursor_ptr >= smap_end)
  235.                 cursor_ptr = scr_map;
  236.             if (*cursor_ptr < ATTR)
  237.                 current_attr = cursor_ptr;
  238.             else {
  239.                 if ((ptr = look_attr(cursor_ptr,BACK)) != NULL)
  240.                     current_attr = ptr;
  241.             }
  242.             setibmcursor();
  243.             return(0);
  244.         }
  245.         case RSLT_LCAC: {    
  246.             /* local action key */
  247.             if (emdp->event_reg & SYS_LOCK)
  248.                 return(-1);
  249.  
  250.             if (localkey(tkptr->entry))
  251.                 entryerr(tkptr);
  252.             break;
  253.         }
  254.         default: {
  255.             if (stdtoken(tkptr))
  256.                 classerr(tkptr);
  257.             return(0);
  258.         }
  259.     }
  260.     emdp->event_reg &= ~CLEAR_KEY;    /* turn off clear flag */
  261.     return(0);
  262. }
  263.  
  264.  
  265.  
  266. unsigned char
  267. pfkeymap(entrycode)
  268. unsigned char entrycode;
  269. {
  270.     switch (entrycode) {
  271.         case PF1:        
  272.             return(RPF1);
  273.         case PF2:        
  274.             return(RPF2);
  275.         case PF3:        
  276.             return(RPF3);
  277.         case PF4:        
  278.             return(RPF4);
  279.         case PF5:        
  280.             return(RPF5);
  281.         case PF6:        
  282.             return(RPF6);
  283.         case PF7:        
  284.             return(RPF7);
  285.         case PF8:        
  286.             return(RPF8);
  287.         case PF9:        
  288.             return(RPF9);
  289.         case PF10:        
  290.             return(RPF10);
  291.         case PF11:
  292.             return(RPF11);
  293.         case PF12:        
  294.             return(RPF12);
  295.         case PF13:        
  296.             return(RPF13);
  297.         case PF14:        
  298.             return(RPF14);
  299.         case PF15:        
  300.             return(RPF15);
  301.         case PF16:        
  302.             return(RPF16);    
  303.         case PF17:        
  304.             return(RPF17);    
  305.         case PF18:        
  306.             return(RPF18);    
  307.         case PF19:        
  308.             return(RPF19);    
  309.         case PF20:        
  310.             return(RPF20);    
  311.         case PF21:        
  312.             return(RPF21);    
  313.         case PF22:        
  314.             return(RPF22);    
  315.         case PF23:        
  316.             return(RPF23);    
  317.         case PF24:        
  318.             return(RPF24);    
  319.         case PA1:        
  320.             return(RPA1);
  321.         case PA2:        
  322.             return(RPA2);
  323.         case PA3:        
  324.             return(RPA3);
  325.         case CLEAR:        
  326.             return(RCLEAR);
  327.         case ENTER:        
  328.             return(RENTER);
  329.         case PFSHIFT:    
  330.             return(0);
  331.         case PFDUBSHIFT:    
  332.             return(0);
  333.     }
  334.     return(0);
  335. }
  336.  
  337.  
  338. doreset()
  339. {
  340.     emdp->event_reg &= ~INSERT;
  341.     emdp->event_reg &= ~KYBD_LOCK;
  342.     emdp->event_reg &= ~SYS_LOCK;
  343.  
  344.     /* reset the flags */
  345.     clrinsert();
  346.     clrkbdlock();
  347.     clrsyslock();
  348. }
  349.  
  350.  
  351. /* TODO this stuff hereafter belongs in an output.c module */
  352.  
  353. ibmsendchar(thechar) 
  354. unsigned char thechar;
  355. {
  356.     register unsigned char *ptr;
  357.     register unsigned char *prevptr;
  358.     int cnt = 0;
  359.     int count;
  360.  
  361.     if (!emdp->connopen)
  362.         return(-1);
  363.  
  364.     if (pastemode == IBMPASTEABORT)
  365.         return(-1);
  366.         
  367.     if (thechar < 32 || thechar == 0xFF)
  368.         /* invalid char, < space had (|| thechar >= 127) and >= DEL */
  369.         return(-1);
  370.  
  371.     if ((current_attr == NULL) 
  372.         || ((*cursor_ptr >= ATTR) && (!(*current_attr & PROT)))) 
  373.     {
  374.         /* we're in an unprotected field, place the new char in it */
  375.         
  376.         if (!(emdp->event_reg & INSERT)) {
  377.             /* standard mode, overwrite current character */
  378.             *cursor_ptr = thechar;
  379.             if (pastemode) {
  380.                 /* wait for caller to draw */
  381.                 set_mod(cursor_ptr, 1);
  382.             }
  383.             else {
  384.                 (*emdp->ch_draw)(thechar, pc_attr());
  385.             }
  386.         }
  387.         else {
  388.             /* we're in insert mode */
  389.             /* count non-nulls remaining in field */
  390.             for (ptr = cursor_ptr; *ptr >= ATTR && *ptr != IBMNULL; cnt++) {
  391.                 if (++ptr == smap_end) 
  392.                     ptr = scr_map;
  393.             }
  394.             if (*ptr < ATTR) {
  395.                 if (emdp->squeezeblanks) {
  396.                     if (ptr == scr_map)
  397.                         ptr = smap_end - 1;
  398.                     else
  399.                         --ptr;
  400.                     if (cnt > 1 && *ptr == ' ') {
  401.                         /* let's squeeze out this trailing blank */
  402.                         --cnt;
  403.                     }
  404.                     else {
  405.                         /* failure */
  406.                         if (pastemode)
  407.                             pastemode = IBMPASTEABORT;
  408.                         else
  409.                             flushactions(emdp);            /* kill all actions on KYBD_LOCK */
  410. #ifdef PROTLOCK
  411.                         emdp->event_reg |= KYBD_LOCK;
  412.                         showkbdlock();
  413.  
  414. #else
  415. /* beep instead of locking the keyboard */
  416.                         beep();
  417. #endif
  418.                         return(0);
  419.                     }
  420.                 }
  421.                 else {
  422.                     if (pastemode)
  423.                         pastemode = IBMPASTEABORT;
  424.                     else
  425.                         flushactions(emdp);            /* kill all actions on KYBD_LOCK */
  426. #ifdef PROTLOCK
  427.                     emdp->event_reg |= KYBD_LOCK;
  428.                     showkbdlock();
  429. #else
  430.                     beep();
  431. #endif
  432.                     return(0);
  433.                 }
  434.             }
  435.             prevptr = ptr - 1;
  436.             cnt++; 
  437.  
  438.             /* we are counting backwards on the screen */
  439.             for (count = cnt - 1; count > 0; --ptr, --prevptr, --count) {
  440.                 if (ptr < scr_map) 
  441.                     ptr += emdp->screensize;
  442.                 if (prevptr < scr_map) {
  443.                     /* wrap around to the bottom of the screen */
  444.                     prevptr += emdp->screensize;
  445.                     *ptr = *prevptr;
  446.                     if (pastemode) {
  447.                         /* wait to draw */
  448.                         set_mod(scr_map, cnt - count);
  449.                     }
  450.                     else {
  451.                         /* put out what so far */
  452.                         (*emdp->str_draw)(scr_map, cnt - count, pc_attr());
  453.                     }
  454.                     cnt = count;
  455.                 }
  456.                 else 
  457.                     *ptr = *prevptr;                /* normal squeeze */
  458.             }
  459.             if (cnt) {
  460.                 *cursor_ptr = thechar;
  461.                 if (pastemode) {
  462.                     /* wait to draw */
  463.                     set_mod(cursor_ptr, cnt);
  464.                 }
  465.                 else {
  466.                     (*emdp->str_draw)(cursor_ptr, cnt, pc_attr());
  467.                 }
  468.             }
  469.         }
  470.         
  471.         if (current_attr) 
  472.             *current_attr |= MDT;
  473.         if (++cursor_ptr == smap_end)
  474.             cursor_ptr = scr_map;
  475.         if (*cursor_ptr < ATTR) {
  476.             /* find next unprotected field */
  477.             
  478.             if (pastemode == IBMPASTEMODE) {
  479.                 /* when pasting into 3270 screen, hitting a new field aborts */
  480.                 pastemode = IBMPASTEABORT;
  481.             }
  482.             cursor_ptr = next_unp(FWD);
  483.             if ((current_attr = cursor_ptr - 1) < scr_map)
  484.                 current_attr += emdp->screensize;
  485.         }
  486.         if (pastemode) {
  487.             newibmcursor();
  488.             emdp->event_reg |= SCREEN_EVENT;
  489.                 /* make sure new chars get drawn */
  490.         }
  491.         else
  492.             setibmcursor();
  493.     } 
  494.     else {
  495.         /* protected field is a no-no */
  496.         if (pastemode == IBMPASTEMODE)
  497.             pastemode = IBMPASTEABORT;
  498.         else
  499.             flushactions(emdp);            /* kill all actions on KYBD_LOCK */
  500. #ifdef PROTLOCK
  501.         emdp->event_reg |= KYBD_LOCK;
  502.         showkbdlock();
  503. #else
  504.         beep();
  505. #endif
  506.     }
  507. }
  508.  
  509.  
  510. /* for compatibility with c19 file transfer */
  511.  
  512. ibmsendftchar(tchar)
  513. unsigned char tchar;
  514. {
  515.     ibmsendchar(tchar);
  516. }
  517.  
  518.  
  519. /* send a string, in this case to the internal 3270 translator */
  520.  
  521. ibmsendstr(strp)
  522. register unsigned char * strp;
  523. {
  524.     while (*strp) 
  525.         ibmsendchar(*strp++);
  526. }
  527.  
  528.  
  529. /* send a pf key, in this case to the internal 3270 translator */
  530.  
  531. ibmsendpf(pfkey)
  532. unsigned char pfkey;
  533. {
  534.     unsigned char tkey;
  535.  
  536.     if (!emdp->connopen)
  537.         return(-1);
  538.  
  539.     if ( !(tkey = pfkeymap(pfkey))) /* save it     */
  540.         return(-1);         
  541.  
  542.     emdp->aid_key = tkey;
  543.  
  544.     emdp->event_reg |= SYS_LOCK;
  545.     showsyslock();
  546.     if (emdp->event_reg & INSERT) {
  547.         /* turn off insert if it's on */
  548.         clrinsert();
  549.         emdp->event_reg &= ~INSERT;
  550.     }
  551.  
  552.     read_mod();                        /* telnet server expects this     */
  553.  
  554.     savescreen();
  555.         /* save the screen before it gets overwritten */
  556.  
  557.     if (pfkey == CLEAR) {
  558.         /* erase screen */
  559.     
  560.         emdp->event_reg |= CLEAR_KEY;            /* set CLEAR-encountered flag */
  561.         cursor_ptr = scr_map;
  562.         current_attr = NULL;
  563.         mem_clear(scr_map,emdp->screensize,(char) IBMNULL);
  564.         (*emdp->clear_scr)();
  565.     }
  566.  
  567.     if (!emdp->typeahead)
  568.         flushactions(emdp);                /* kill all actions on SYS_LOCK if typeahead off */
  569.  
  570.     return(-1);         
  571. }
  572.  
  573.  
  574. localkey(code)
  575. unsigned char code;
  576. {
  577.     register unsigned char * ptr;
  578.     register unsigned char * nextattr;
  579.     register unsigned char * nextp;
  580.     unsigned char *stake;
  581.     register int cnt;
  582.  
  583.     switch (code) {
  584.         case INSRT: {
  585.             emdp->event_reg ^= INSERT;
  586.             if (emdp->event_reg & INSERT)
  587.                 showinsert();
  588.             else
  589.                 clrinsert();
  590.             break;
  591.         }
  592.         case ERASE_EOF:  {
  593.             if ((current_attr == NULL) || !(*current_attr & PROT)) {
  594.                 if (current_attr != NULL)         
  595.                     /* if formatted buffer stop at attr    */
  596.                     nextattr = look_attr(cursor_ptr, FWD);
  597.                 else 
  598.                     /* go to end of screen*/
  599.                     nextattr = smap_end;              
  600.                 stake = ptr = cursor_ptr;
  601.                 for (cnt = 0; ptr != nextattr; ) {    
  602.                     if (ptr == smap_end) {
  603.                         ptr = scr_map;
  604.                         continue;
  605.                     }
  606.                     *ptr++ = IBMNULL;
  607.                     cnt++;
  608.                 }
  609.                 if (cnt) {
  610.                     (*emdp->str_draw)(stake, cnt, pc_attr());
  611.                     if (current_attr != NULL)             /* if formatted buffer     */
  612.                         *current_attr |= MDT;           /* turn on MDT         */
  613.                 }
  614.             }
  615.             else {
  616.                 /* protected field */
  617.                 flushactions(emdp);            /* kill all actions on KYBD_LOCK */
  618. #ifdef PROTLOCK
  619.                 emdp->event_reg |= KYBD_LOCK;
  620.                 showkbdlock();
  621.  
  622. #else
  623.                 beep();
  624. #endif
  625.             }
  626.             break;
  627.         }
  628.         case INPUT_ERASE: {
  629.             if (current_attr != NULL) {
  630.                 eau();                    /* erase all unprotected */
  631.             }
  632.             else {
  633.                 cursor_ptr = scr_map;
  634.                 modflg = emdp->modflg = (long) SCRALLMOD;
  635.                 for (ptr = scr_map; ptr < smap_end; ) 
  636.                     *ptr++ = IBMNULL;
  637.             }
  638.             emdp->event_reg |= SCREEN_EVENT;
  639.             setibmcursor();
  640.             break;
  641.         }
  642.         case BACKSP_BLANK: {
  643.             /* first backspace */
  644.             unsigned char * curstmp;
  645.             unsigned char * atttmp;
  646.  
  647.             if (*cursor_ptr < ATTR)
  648.                 /* new attribute */
  649.                 if ((ptr = look_attr(cursor_ptr, BACK)) != NULL)
  650.                     current_attr = ptr;
  651.             if (--cursor_ptr < scr_map) 
  652.                 cursor_ptr += emdp->screensize;
  653.  
  654.             newibmcursor();
  655.             if (! (*cursor_ptr < ATTR)) {
  656.                 if (current_attr == NULL || !(*current_attr & PROT)) {
  657.                     /* OK to blank out unprotected char */
  658.                     
  659.                     curstmp = cursor_ptr;
  660.                     atttmp = current_attr;
  661.                     
  662.                     ibmsendchar(' ');
  663.                     
  664.                     /* go back again to where we were */
  665.                     cursor_ptr = curstmp;
  666.                     current_attr = atttmp;
  667.                 }
  668.             }
  669.             setibmcursor();
  670.             break;
  671.         }
  672.         case BACKSP_DEL: {
  673.             if (*cursor_ptr < ATTR)
  674.                 if ((ptr = look_attr(cursor_ptr, BACK)) != NULL)
  675.                     current_attr = ptr;
  676.             if (--cursor_ptr < scr_map) 
  677.                 cursor_ptr += emdp->screensize;
  678.             newibmcursor();
  679.             /* fall through to do a delete */
  680.         }
  681.         case DEL_CHAR: {
  682.             /* doesn't work on an unformatted buffer--??? kev */
  683.             
  684.             int ymod;
  685.             int ylast;
  686.             
  687.             if ((current_attr != NULL) 
  688.                 && (*cursor_ptr >= ATTR) 
  689.                 && !(*current_attr & PROT)) 
  690.             {
  691.                 nextattr = look_attr(cursor_ptr, FWD);
  692.                 ptr = nextp = stake = cursor_ptr;
  693.                 
  694.                 if (!emdp->shiftfield) {
  695.                     /* delete only to next attr or end of line, standard behavior */
  696.                     if (nextattr < ptr || (nextattr - scr_map) / emdp->linelength != ypos)
  697.                         nextattr = scr_map + emdp->linelength * (ypos + 1); 
  698.  
  699.                     for (cnt = 0; ptr != nextattr; cnt++, ptr++) {
  700.                         if ((ptr + 1) != nextattr) 
  701.                             *ptr = *(ptr + 1);         /* march left */
  702.                         else 
  703.                             *ptr = IBMNULL;                /* or pad with nulls */
  704.                     }
  705.                     /* display results now */
  706.                     if (cnt) {
  707.                         (*emdp->str_draw)(stake, cnt, pc_attr());
  708.                         *current_attr |= MDT;         /* turn on MDT */
  709.                     }
  710.                 }
  711.                 else {
  712.                     /* shift whole field over */
  713.                     if (++nextp >= smap_end)
  714.                         nextp = scr_map;
  715.                     while (nextp != nextattr) {
  716.                         *ptr = *nextp;         /* shift left */
  717.                         if (++ptr >= smap_end)
  718.                             ptr = scr_map;
  719.                         if (++nextp >= smap_end)
  720.                             nextp = scr_map;
  721.                     }
  722.                     *ptr = IBMNULL;                        /* pad with null at end */
  723.                     *current_attr |= MDT;                /* turn on MDT */
  724.                     
  725.                     /* update display */
  726.                     if (nextattr < stake) {
  727.                         /* wrapped, must do 2 set_mods */
  728.                         set_mod(stake, smap_end - stake);
  729.                         set_mod(scr_map, nextattr - scr_map);
  730.                     }
  731.                     else {
  732.                         set_mod(stake, nextattr - stake);
  733.                     }
  734.                     emdp->event_reg |= SCREEN_EVENT;
  735.                 }
  736.             }
  737.             else 
  738.             {
  739.                 /* we're in a protected field */
  740.                 flushactions(emdp);            /* kill all actions on KYBD_LOCK */
  741. #ifdef PROTLOCK
  742.                 emdp->event_reg |= KYBD_LOCK;
  743.                 showkbdlock();
  744. #else
  745.                 beep();
  746. #endif
  747.             }
  748.             break;
  749.         }
  750.         case RESET:  {
  751.             doreset();
  752.             break;
  753.         }
  754.         default: {
  755.             return(TRUE);
  756.         }
  757.     }
  758.     return(FALSE);
  759. }
  760.  
  761.  
  762.  
  763. ibmmvcurs(entry)
  764. unsigned short entry;
  765. {
  766.     register int cnt;
  767.     unsigned char *ptr;
  768.  
  769.     switch (entry) {
  770.         case LEFT_ARROW:  {
  771.             if (*cursor_ptr < ATTR)                /* move the cursor to the left */
  772.                 if ((ptr = look_attr(cursor_ptr,BACK)) != NULL)
  773.                     current_attr = ptr;            
  774.             if (--cursor_ptr < scr_map)
  775.                 cursor_ptr += emdp->screensize;
  776.             break;
  777.         }
  778.         case RIGHT_ARROW:  {
  779.             if (++cursor_ptr >= smap_end)        /* move the cursor to     */
  780.                 cursor_ptr -= emdp->screensize;        /* the right wrap around*/
  781.             if (*cursor_ptr < ATTR) {
  782.                 current_attr = cursor_ptr;
  783.             }
  784.             break;
  785.         }
  786.         case UP_ARROW:  {
  787.             if ((cursor_ptr -= emdp->linelength) < scr_map)/* move the cursor */
  788.                 cursor_ptr += emdp->screensize;        /* up one line - wrap if*/
  789.             if (*cursor_ptr < ATTR)                /* necessary  also reset*/
  790.                 current_attr = cursor_ptr;        /* the current attribute*/
  791.             else                                /* field                */
  792.                 if ((ptr = look_attr(cursor_ptr,BACK)) != NULL)
  793.                     current_attr = ptr;
  794.             break;
  795.         }
  796.         case DOWN_ARROW:  {
  797.             if ((cursor_ptr += emdp->linelength) >= smap_end)/* move the     */
  798.                 cursor_ptr -= emdp->screensize;        /* down one line wrap if*/
  799.             if (*cursor_ptr < ATTR)                /* necessary  also reset*/
  800.                 current_attr = cursor_ptr;        /* the current attribute*/
  801.             else                                /* field                */
  802.                 if ((ptr = look_attr(cursor_ptr,BACK)) != NULL)
  803.                     current_attr = ptr;
  804.             break;
  805.         }
  806.         case HOME:  {
  807.             cursor_ptr = smap_end - 1;
  808.             if ((cursor_ptr = next_unp (FWD)) == (smap_end - 1))
  809.                 cursor_ptr = scr_map;
  810.             if (current_attr != NULL)
  811.                 if ((current_attr = cursor_ptr - 1) < scr_map) 
  812.                     current_attr += emdp->screensize;
  813.             break;
  814.         }
  815.         case NEW_LINE:  {
  816.             cnt = (((cursor_ptr - scr_map) / emdp->linelength) + 1) * emdp->linelength;
  817.             if (cnt == emdp->screensize)
  818.                 cnt = 0;
  819.             cursor_ptr = scr_map + cnt;
  820.             if (*cursor_ptr >= ATTR) {
  821.                 /* if not attribute, find next attrib */
  822.                 if ((current_attr = look_attr(cursor_ptr,BACK)) == NULL)
  823.                     break;
  824.                 if (! (*current_attr & PROT))
  825.                     /* not protected, we don't need to skip to next field */
  826.                     break;
  827.                 if (pastemode) {
  828.                     /* protected, abort pastemode when we land in protected field */
  829.                     pastemode = IBMPASTEABORT;            /* abort pastemode */
  830.                     break;
  831.                 }
  832.             }
  833.             else if (pastemode && (*cursor_ptr & PROT)) {
  834.                 /* abort pastemode if we land in protected field */
  835.                 current_attr = cursor_ptr;
  836.                 pastemode = IBMPASTEABORT;            /* abort pastemode */
  837.                 break;
  838.             }
  839.             /* else fall through & set on next unprotected */
  840.         }
  841.         case TAB_FWD:
  842.         case BACK_TAB:  {
  843.             cursor_ptr = next_unp((entry == BACK_TAB) ? BACK : FWD);
  844.             if ((current_attr = cursor_ptr - 1) < scr_map) 
  845.                 current_attr += emdp->screensize;
  846.             if (*current_attr >= ATTR || (*current_attr & PROT)) {
  847.                 cursor_ptr = scr_map;
  848.                 current_attr = look_attr(scr_map,BACK);
  849.             }
  850.             break;
  851.         }
  852.         default: {
  853.             return(TRUE);
  854.         }
  855.     }
  856.     return(FALSE);
  857. }
  858.  
  859.  
  860.